home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / mint / shells / tcshsrc.zoo / tcsh / sh.parse.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-10-25  |  13.7 KB  |  687 lines

  1. /* $Header: /home/hyperion/mu/christos/src/sys/tcsh-6.00/RCS/sh.parse.c,v 3.2 1991/07/15 19:37:24 christos Exp $ */
  2. /*
  3.  * sh.parse.c: Interpret a list of tokens
  4.  */
  5. /*-
  6.  * Copyright (c) 1980, 1991 The Regents of the University of California.
  7.  * All rights reserved.
  8.  *
  9.  * Redistribution and use in source and binary forms, with or without
  10.  * modification, are permitted provided that the following conditions
  11.  * are met:
  12.  * 1. Redistributions of source code must retain the above copyright
  13.  *    notice, this list of conditions and the following disclaimer.
  14.  * 2. Redistributions in binary form must reproduce the above copyright
  15.  *    notice, this list of conditions and the following disclaimer in the
  16.  *    documentation and/or other materials provided with the distribution.
  17.  * 3. All advertising materials mentioning features or use of this software
  18.  *    must display the following acknowledgement:
  19.  *    This product includes software developed by the University of
  20.  *    California, Berkeley and its contributors.
  21.  * 4. Neither the name of the University nor the names of its contributors
  22.  *    may be used to endorse or promote products derived from this software
  23.  *    without specific prior written permission.
  24.  *
  25.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  26.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  27.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  28.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  29.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  30.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  31.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  32.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  33.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  34.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  35.  * SUCH DAMAGE.
  36.  */
  37. #include "config.h"
  38. RCSID("$Id: sh.parse.c,v 3.2 1991/07/15 19:37:24 christos Exp $")
  39.  
  40. #include "sh.h"
  41.  
  42. /*
  43.  * C shell
  44.  */
  45. static    void         asyntax __P((struct wordent *, struct wordent *));
  46. static    void         asyn0      __P((struct wordent *, struct wordent *));
  47. static    void         asyn3     __P((struct wordent *, struct wordent *));
  48. static    struct wordent    *freenod __P((struct wordent *, struct wordent *));
  49. static    struct command    *syn0     __P((struct wordent *, struct wordent *, int));
  50. static    struct command    *syn1     __P((struct wordent *, struct wordent *, int));
  51. static    struct command    *syn1a     __P((struct wordent *, struct wordent *, int));
  52. static    struct command    *syn1b     __P((struct wordent *, struct wordent *, int));
  53. static    struct command    *syn2     __P((struct wordent *, struct wordent *, int));
  54. static    struct command    *syn3     __P((struct wordent *, struct wordent *, int));
  55.  
  56. #define ALEFT    51        /* max of 50 alias expansions     */
  57. #define HLEFT    11        /* max of 10 history expansions */
  58. /*
  59.  * Perform aliasing on the word list lex
  60.  * Do a (very rudimentary) parse to separate into commands.
  61.  * If word 0 of a command has an alias, do it.
  62.  * Repeat a maximum of 50 times.
  63.  */
  64. static int aleft;
  65. extern int hleft;
  66. void
  67. alias(lex)
  68.     register struct wordent *lex;
  69. {
  70.     jmp_buf osetexit;
  71.  
  72.     aleft = ALEFT;
  73.     hleft = HLEFT;
  74.     getexit(osetexit);
  75.     (void) setexit();
  76.     if (haderr) {
  77.     resexit(osetexit);
  78.     reset();
  79.     }
  80.     if (--aleft == 0)
  81.     stderror(ERR_ALIASLOOP);
  82.     asyntax(lex->next, lex);
  83.     resexit(osetexit);
  84. }
  85.  
  86. static void
  87. asyntax(p1, p2)
  88.     register struct wordent *p1, *p2;
  89. {
  90.     while (p1 != p2)
  91.     if (any(";&\n", p1->word[0]))
  92.         p1 = p1->next;
  93.     else {
  94.         asyn0(p1, p2);
  95.         return;
  96.     }
  97. }
  98.  
  99. static void
  100. asyn0(p1, p2)
  101.     struct wordent *p1;
  102.     register struct wordent *p2;
  103. {
  104.     register struct wordent *p;
  105.     register int l = 0;
  106.  
  107.     for (p = p1; p != p2; p = p->next)
  108.     switch (p->word[0]) {
  109.  
  110.     case '(':
  111.         l++;
  112.         continue;
  113.  
  114.     case ')':
  115.         l--;
  116.         if (l < 0)
  117.         stderror(ERR_TOOMANYRP);
  118.         continue;
  119.  
  120.     case '>':
  121.         if (p->next != p2 && eq(p->next->word, STRand))
  122.         p = p->next;
  123.         continue;
  124.  
  125.     case '&':
  126.     case '|':
  127.     case ';':
  128.     case '\n':
  129.         if (l != 0)
  130.         continue;
  131.         asyn3(p1, p);
  132.         asyntax(p->next, p2);
  133.         return;
  134.     }
  135.     if (l == 0)
  136.     asyn3(p1, p2);
  137. }
  138.  
  139. static void
  140. asyn3(p1, p2)
  141.     struct wordent *p1;
  142.     register struct wordent *p2;
  143. {
  144.     register struct varent *ap;
  145.     struct wordent alout;
  146.     register bool redid;
  147.  
  148.     if (p1 == p2)
  149.     return;
  150.     if (p1->word[0] == '(') {
  151.     for (p2 = p2->prev; p2->word[0] != ')'; p2 = p2->prev)
  152.         if (p2 == p1)
  153.         return;
  154.     if (p2 == p1->next)
  155.         return;
  156.     asyn0(p1->next, p2);
  157.     return;
  158.     }
  159.     ap = adrof1(p1->word, &aliases);
  160.     if (ap == 0)
  161.     return;
  162.     alhistp = p1->prev;
  163.     alhistt = p2;
  164.     alvec = ap->vec;
  165.     redid = lex(&alout);
  166.     alhistp = alhistt = 0;
  167.     alvec = 0;
  168.     if (seterr) {
  169.     freelex(&alout);
  170.     stderror(ERR_OLD);
  171.     }
  172.     if (p1->word[0] && eq(p1->word, alout.next->word)) {
  173.     Char   *cp = alout.next->word;
  174.  
  175.     alout.next->word = Strspl(STRQNULL, cp);
  176.     xfree((ptr_t) cp);
  177.     }
  178.     p1 = freenod(p1, redid ? p2 : p1->next);
  179.     if (alout.next != &alout) {
  180.     p1->next->prev = alout.prev->prev;
  181.     alout.prev->prev->next = p1->next;
  182.     alout.next->prev = p1;
  183.     p1->next = alout.next;
  184.     xfree((ptr_t) alout.prev->word);
  185.     xfree((ptr_t) (alout.prev));
  186.     }
  187.     reset();            /* throw! */
  188. }
  189.  
  190. static struct wordent *
  191. freenod(p1, p2)
  192.     register struct wordent *p1, *p2;
  193. {
  194.     register struct wordent *retp = p1->prev;
  195.  
  196.     while (p1 != p2) {
  197.     xfree((ptr_t) p1->word);
  198.     p1 = p1->next;
  199.     xfree((ptr_t) (p1->prev));
  200.     }
  201.     retp->next = p2;
  202.     p2->prev = retp;
  203.     return (retp);
  204. }
  205.  
  206. #define    P_HERE    1
  207. #define    P_IN    2
  208. #define    P_OUT    4
  209. #define    P_DIAG    8
  210.  
  211. /*
  212.  * syntax
  213.  *    empty
  214.  *    syn0
  215.  */
  216. struct command *
  217. syntax(p1, p2, flags)
  218.     register struct wordent *p1, *p2;
  219.     int     flags;
  220. {
  221.  
  222.     while (p1 != p2)
  223.     if (any(";&\n", p1->word[0]))
  224.         p1 = p1->next;
  225.     else
  226.         return (syn0(p1, p2, flags));
  227.     return (0);
  228. }
  229.  
  230. /*
  231.  * syn0
  232.  *    syn1
  233.  *    syn1 & syntax
  234.  */
  235. static struct command *
  236. syn0(p1, p2, flags)
  237.     struct wordent *p1, *p2;
  238.     int     flags;
  239. {
  240.     register struct wordent *p;
  241.     register struct command *t, *t1;
  242.     int     l;
  243.  
  244.     l = 0;
  245.     for (p = p1; p != p2; p = p->next)
  246.     switch (p->word[0]) {
  247.  
  248.     case '(':
  249.         l++;
  250.         continue;
  251.  
  252.     case ')':
  253.         l--;
  254.         if (l < 0)
  255.         seterror(ERR_TOOMANYRP);
  256.         continue;
  257.  
  258.     case '|':
  259.         if (p->word[1] == '|')
  260.         continue;
  261.         /* fall into ... */
  262.  
  263.     case '>':
  264.         if (p->next != p2 && eq(p->next->word, STRand))
  265.         p = p->next;
  266.         continue;
  267.  
  268.     case '&':
  269.         if (l != 0)
  270.         break;
  271.         if (p->word[1] == '&')
  272.         continue;
  273.         t1 = syn1(p1, p, flags);
  274.         if (t1->t_dtyp == NODE_LIST ||
  275.         t1->t_dtyp == NODE_AND ||
  276.         t1->t_dtyp == NODE_OR) {
  277.         t = (struct command *) xcalloc(1, sizeof(*t));
  278.         t->t_dtyp = NODE_PAREN;
  279.         t->t_dflg = F_AMPERSAND | F_NOINTERRUPT;
  280.         t->t_dspr = t1;
  281.         t1 = t;
  282.         }
  283.         else
  284.         t1->t_dflg |= F_AMPERSAND | F_NOINTERRUPT;
  285.         t = (struct command *) xcalloc(1, sizeof(*t));
  286.         t->t_dtyp = NODE_LIST;
  287.         t->t_dflg = 0;
  288.         t->t_dcar = t1;
  289.         t->t_dcdr = syntax(p, p2, flags);
  290.         return (t);
  291.     }
  292.     if (l == 0)
  293.     return (syn1(p1, p2, flags));
  294.     seterror(ERR_TOOMANYLP);
  295.     return (0);
  296. }
  297.  
  298. /*
  299.  * syn1
  300.  *    syn1a
  301.  *    syn1a ; syntax
  302.  */
  303. static struct command *
  304. syn1(p1, p2, flags)
  305.     struct wordent *p1, *p2;
  306.     int     flags;
  307. {
  308.     register struct wordent *p;
  309.     register struct command *t;
  310.     int     l;
  311.  
  312.     l = 0;
  313.     for (p = p1; p != p2; p = p->next)
  314.     switch (p->word[0]) {
  315.  
  316.     case '(':
  317.         l++;
  318.         continue;
  319.  
  320.     case ')':
  321.         l--;
  322.         continue;
  323.  
  324.     case ';':
  325.     case '\n':
  326.         if (l != 0)
  327.         break;
  328.         t = (struct command *) xcalloc(1, sizeof(*t));
  329.         t->t_dtyp = NODE_LIST;
  330.         t->t_dcar = syn1a(p1, p, flags);
  331.         t->t_dcdr = syntax(p->next, p2, flags);
  332.         if (t->t_dcdr == 0)
  333.         t->t_dcdr = t->t_dcar, t->t_dcar = 0;
  334.         return (t);
  335.     }
  336.     return (syn1a(p1, p2, flags));
  337. }
  338.  
  339. /*
  340.  * syn1a
  341.  *    syn1b
  342.  *    syn1b || syn1a
  343.  */
  344. static struct command *
  345. syn1a(p1, p2, flags)
  346.     struct wordent *p1, *p2;
  347.     int     flags;
  348. {
  349.     register struct wordent *p;
  350.     register struct command *t;
  351.     register int l = 0;
  352.  
  353.     for (p = p1; p != p2; p = p->next)
  354.     switch (p->word[0]) {
  355.  
  356.     case '(':
  357.         l++;
  358.         continue;
  359.  
  360.     case ')':
  361.         l--;
  362.         continue;
  363.  
  364.     case '|':
  365.         if (p->word[1] != '|')
  366.         continue;
  367.         if (l == 0) {
  368.         t = (struct command *) xcalloc(1, sizeof(*t));
  369.         t->t_dtyp = NODE_OR;
  370.         t->t_dcar = syn1b(p1, p, flags);
  371.         t->t_dcdr = syn1a(p->next, p2, flags);
  372.         t->t_dflg = 0;
  373.         return (t);
  374.         }
  375.         continue;
  376.     }
  377.     return (syn1b(p1, p2, flags));
  378. }
  379.  
  380. /*
  381.  * syn1b
  382.  *    syn2
  383.  *    syn2 && syn1b
  384.  */
  385. static struct command *
  386. syn1b(p1, p2, flags)
  387.     struct wordent *p1, *p2;
  388.     int     flags;
  389. {
  390.     register struct wordent *p;
  391.     register struct command *t;
  392.     register int l = 0;
  393.  
  394.     for (p = p1; p != p2; p = p->next)
  395.     switch (p->word[0]) {
  396.  
  397.     case '(':
  398.         l++;
  399.         continue;
  400.  
  401.     case ')':
  402.         l--;
  403.         continue;
  404.  
  405.     case '&':
  406.         if (p->word[1] == '&' && l == 0) {
  407.         t = (struct command *) xcalloc(1, sizeof(*t));
  408.         t->t_dtyp = NODE_AND;
  409.         t->t_dcar = syn2(p1, p, flags);
  410.         t->t_dcdr = syn1b(p->next, p2, flags);
  411.         t->t_dflg = 0;
  412.         return (t);
  413.         }
  414.         continue;
  415.     }
  416.     return (syn2(p1, p2, flags));
  417. }
  418.  
  419. /*
  420.  * syn2
  421.  *    syn3
  422.  *    syn3 | syn2
  423.  *    syn3 |& syn2
  424.  */
  425. static struct command *
  426. syn2(p1, p2, flags)
  427.     struct wordent *p1, *p2;
  428.     int     flags;
  429. {
  430.     register struct wordent *p, *pn;
  431.     register struct command *t;
  432.     register int l = 0;
  433.     int     f;
  434.  
  435.     for (p = p1; p != p2; p = p->next)
  436.     switch (p->word[0]) {
  437.  
  438.     case '(':
  439.         l++;
  440.         continue;
  441.  
  442.     case ')':
  443.         l--;
  444.         continue;
  445.  
  446.     case '|':
  447.         if (l != 0)
  448.         continue;
  449.         t = (struct command *) xcalloc(1, sizeof(*t));
  450.         f = flags | P_OUT;
  451.         pn = p->next;
  452.         if (pn != p2 && pn->word[0] == '&') {
  453.         f |= P_DIAG;
  454.         t->t_dflg |= F_STDERR;
  455.         }
  456.         t->t_dtyp = NODE_PIPE;
  457.         t->t_dcar = syn3(p1, p, f);
  458.         if (pn != p2 && pn->word[0] == '&')
  459.         p = pn;
  460.         t->t_dcdr = syn2(p->next, p2, flags | P_IN);
  461.         return (t);
  462.     }
  463.     return (syn3(p1, p2, flags));
  464. }
  465.  
  466. static char RELPAR[] = {'<', '>', '(', ')', '\0'};
  467.  
  468. /*
  469.  * syn3
  470.  *    ( syn0 ) [ < in  ] [ > out ]
  471.  *    word word* [ < in ] [ > out ]
  472.  *    KEYWORD ( word* ) word* [ < in ] [ > out ]
  473.  *
  474.  *    KEYWORD = (@ exit foreach if set switch test while)
  475.  */
  476. static struct command *
  477. syn3(p1, p2, flags)
  478.     struct wordent *p1, *p2;
  479.     int     flags;
  480. {
  481.     register struct wordent *p;
  482.     struct wordent *lp, *rp;
  483.     register struct command *t;
  484.     register int l;
  485.     Char  **av;
  486.     int     n, c;
  487.     bool    specp = 0;
  488.  
  489.     if (p1 != p2) {
  490.     p = p1;
  491. again:
  492.     switch (srchx(p->word)) {
  493.  
  494.     case T_ELSE:
  495.         p = p->next;
  496.         if (p != p2)
  497.         goto again;
  498.         break;
  499.  
  500.     case T_EXIT:
  501.     case T_FOREACH:
  502.     case T_IF:
  503.     case T_LET:
  504.     case T_SET:
  505.     case T_SWITCH:
  506.     case T_WHILE:
  507.         specp = 1;
  508.         break;
  509.     }
  510.     }
  511.     n = 0;
  512.     l = 0;
  513.     for (p = p1; p != p2; p = p->next)
  514.     switch (p->word[0]) {
  515.  
  516.     case '(':
  517.         if (specp)
  518.         n++;
  519.         l++;
  520.         continue;
  521.  
  522.     case ')':
  523.         if (specp)
  524.         n++;
  525.         l--;
  526.         continue;
  527.  
  528.     case '>':
  529.     case '<':
  530.         if (l != 0) {
  531.         if (specp)
  532.             n++;
  533.         continue;
  534.         }
  535.         if (p->next == p2)
  536.         continue;
  537.         if (any(RELPAR, p->next->word[0]))
  538.         continue;
  539.         n--;
  540.         continue;
  541.  
  542.     default:
  543.         if (!specp && l != 0)
  544.         continue;
  545.         n++;
  546.         continue;
  547.     }
  548.     if (n < 0)
  549.     n = 0;
  550.     t = (struct command *) xcalloc(1, sizeof(*t));
  551.     av = (Char **) xcalloc((size_t) (n + 1), sizeof(Char **));
  552.     t->t_dcom = av;
  553.     n = 0;
  554.     if (p2->word[0] == ')')
  555.     t->t_dflg = F_NOFORK;
  556.     lp = 0;
  557.     rp = 0;
  558.     l = 0;
  559.     for (p = p1; p != p2; p = p->next) {
  560.     c = p->word[0];
  561.     switch (c) {
  562.  
  563.     case '(':
  564.         if (l == 0) {
  565.         if (lp != 0 && !specp)
  566.             seterror(ERR_BADPLP);
  567.         lp = p->next;
  568.         }
  569.         l++;
  570.         goto savep;
  571.  
  572.     case ')':
  573.         l--;
  574.         if (l == 0)
  575.         rp = p;
  576.         goto savep;
  577.  
  578.     case '>':
  579.         if (l != 0)
  580.         goto savep;
  581.         if (p->word[1] == '>')
  582.         t->t_dflg |= F_APPEND;
  583.         if (p->next != p2 && eq(p->next->word, STRand)) {
  584.         t->t_dflg |= F_STDERR, p = p->next;
  585.         if (flags & (P_OUT | P_DIAG)) {
  586.             seterror(ERR_OUTRED);
  587.             continue;
  588.         }
  589.         }
  590.         if (p->next != p2 && eq(p->next->word, STRbang))
  591.         t->t_dflg |= F_OVERWRITE, p = p->next;
  592.         if (p->next == p2) {
  593.         seterror(ERR_MISRED);
  594.         continue;
  595.         }
  596.         p = p->next;
  597.         if (any(RELPAR, p->word[0])) {
  598.         seterror(ERR_MISRED);
  599.         continue;
  600.         }
  601.         if ((flags & P_OUT) && (flags & P_DIAG) == 0 || t->t_drit)
  602.         seterror(ERR_OUTRED);
  603.         else
  604.         t->t_drit = Strsave(p->word);
  605.         continue;
  606.  
  607.     case '<':
  608.         if (l != 0)
  609.         goto savep;
  610.         if (p->word[1] == '<')
  611.         t->t_dflg |= F_READ;
  612.         if (p->next == p2) {
  613.         seterror(ERR_MISRED);
  614.         continue;
  615.         }
  616.         p = p->next;
  617.         if (any(RELPAR, p->word[0])) {
  618.         seterror(ERR_MISRED);
  619.         continue;
  620.         }
  621.         if ((flags & P_HERE) && (t->t_dflg & F_READ))
  622.         seterror(ERR_REDPAR);
  623.         else if ((flags & P_IN) || t->t_dlef)
  624.         seterror(ERR_INRED);
  625.         else
  626.         t->t_dlef = Strsave(p->word);
  627.         continue;
  628.  
  629.     savep:
  630.         if (!specp)
  631.         continue;
  632.     default:
  633.         if (l != 0 && !specp)
  634.         continue;
  635.         if (seterr == 0)
  636.         av[n] = Strsave(p->word);
  637.         n++;
  638.         continue;
  639.     }
  640.     }
  641.     if (lp != 0 && !specp) {
  642.     if (n != 0)
  643.         seterror(ERR_BADPLPS);
  644.     t->t_dtyp = NODE_PAREN;
  645.     t->t_dspr = syn0(lp, rp, P_HERE);
  646.     }
  647.     else {
  648.     if (n == 0)
  649.         seterror(ERR_NULLCOM);
  650.     t->t_dtyp = NODE_COMMAND;
  651.     }
  652.     return (t);
  653. }
  654.  
  655. void
  656. freesyn(t)
  657.     register struct command *t;
  658. {
  659.     register Char **v;
  660.  
  661.     if (t == 0)
  662.     return;
  663.     switch (t->t_dtyp) {
  664.  
  665.     case NODE_COMMAND:
  666.     for (v = t->t_dcom; *v; v++)
  667.         xfree((ptr_t) * v);
  668.     xfree((ptr_t) (t->t_dcom));
  669.     xfree((ptr_t) t->t_dlef);
  670.     xfree((ptr_t) t->t_drit);
  671.     break;
  672.     case NODE_PAREN:
  673.     freesyn(t->t_dspr);
  674.     xfree((ptr_t) t->t_dlef);
  675.     xfree((ptr_t) t->t_drit);
  676.     break;
  677.  
  678.     case NODE_AND:
  679.     case NODE_OR:
  680.     case NODE_PIPE:
  681.     case NODE_LIST:
  682.     freesyn(t->t_dcar), freesyn(t->t_dcdr);
  683.     break;
  684.     }
  685.     xfree((ptr_t) t);
  686. }
  687.